package graph;

import java.util.*;

/**
 * 卡100.岛屿最大面积
 * 题目描述
 * 给定一个由 1（陆地）和 0（水）组成的矩阵，计算岛屿的最大面积。岛屿面积的计算方式为组成岛屿的陆地的总数。岛屿由水平方向或垂直方向上相邻的陆地连接而成，并且四周都是水域。你可以假设矩阵外均被水包围。
 * 输入描述
 * 第一行包含两个整数 N, M，表示矩阵的行数和列数。后续 N 行，每行包含 M 个数字，数字为 1 或者 0，表示岛屿的单元格。
 * 输出描述
 * 输出一个整数，表示岛屿的最大面积。如果不存在岛屿，则输出 0。
 */
public class maxisland {
    /**
     * 一刷
     */
    class bfs {
        static int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 顺时针方向：右、下、左、上

        public static int bfs(int[][] grid, boolean[][] visited, int x, int y) {
            Queue<int[]> queue = new LinkedList<>();
            queue.add(new int[]{x, y});
            visited[x][y] = true; // 标记为已访问
            int area = 0; // 当前岛屿的面积

            while (!queue.isEmpty()) {
                int[] current = queue.poll();
                int curX = current[0];
                int curY = current[1];
                area++; // 计算面积

                for (int i = 0; i < 4; i++) {
                    int nextX = curX + dir[i][0];
                    int nextY = curY + dir[i][1];

                    // 检查越界和访问状态
                    if (nextX >= 0 && nextX < grid.length && nextY >= 0 && nextY < grid[0].length
                            && !visited[nextX][nextY] && grid[nextX][nextY] == 1) {
                        queue.add(new int[]{nextX, nextY});
                        visited[nextX][nextY] = true; // 标记为已访问
                    }
                }
            }

            return area; // 返回当前岛屿的面积
        }

        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int m = sc.nextInt();
            int n = sc.nextInt();
            int[][] grid = new int[m][n];
            boolean[][] visited = new boolean[m][n];

            // 读取矩阵数据
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    grid[i][j] = sc.nextInt();
                }
            }

            int maxArea = 0; // 记录最大岛屿面积

            // 遍历整个矩阵
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    // 如果找到未访问的陆地，则使用 BFS 计算面积
                    if (!visited[i][j] && grid[i][j] == 1) {
                        int currentArea = bfs(grid, visited, i, j);
                        maxArea = Math.max(maxArea, currentArea); // 更新最大面积
                    }
                }
            }

            System.out.println(maxArea); // 输出最大面积
            sc.close(); // 关闭 Scanner
        }
    }

    /**
     * 二刷
     */
    class dfs {

        static int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        static int res = 0;
        static int ans = 0;

        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[][] grid = new int[n][m];
            boolean[][] visited = new boolean[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    grid[i][j] = sc.nextInt();
                }
            }

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (!visited[i][j] && grid[i][j] == 1) {
                        ans = 1;
                        visited[i][j] = true;
                        dfs(grid, visited, i, j);
                        res = Math.max(res, ans);
                    }
                }
            }

            System.out.println(res);
        }

        public static void dfs(int[][] grid, boolean[][] visited, int x, int y) {
            for (int i = 0; i < 4; i++) {
                int nextX = x + dir[i][0];
                int nextY = y + dir[i][1];
                if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) continue;

                if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {
                    ans++;
                    visited[nextX][nextY] = true;
                    dfs(grid, visited, nextX, nextY);
                }
            }
        }
    }
}
